//
//  SHKQQWeiBoV2.m
//  ShareKit4QC
//
//  Created by 凯 赵 on 12-5-13.
//  Copyright (c) 2012年 __MyCompanyName__. All rights reserved.
//

#import "SHKQQWeiBoV2.h"
#import "SHK.h"
#import "NSString+URLEncoding.h"
#import "SHKQQWeiBoV2OAuthView.h"
#import "JSONKit.h"
#import "NSHTTPCookieStorage+DeleteForURL.h"


static NSString *authorizeURL = @"https://open.t.qq.com/cgi-bin/oauth2/authorize";
//app key 信息
//static NSString* qqWeiboV2ClientId =@"801146929";
//static NSString* qqWeiboV2SecretKey =@"18668d17926ab885afe2d3c644de4771";
//static NSString* qqWeiboV2RedirectURI =@"http://caitu.me";
//app key 掌上千尺
static NSString* qqWeiboV2ClientId =@"1022866087";
static NSString* qqWeiboV2SecretKey =@"b94278f21c1ffb4568d3d5439fd2898f";
static NSString* qqWeiboV2RedirectURI =@"http://www.1000chi.com";
//鉴权字段
static NSString *accessTokenKey = @"accessToken";
static NSString *usrname=@"usrname";
static NSString *expires_inKey=@"expires_in";
static NSString *openid=@"openid";
static NSString *openkey=@"openkey";

@interface QQWeiBoV2()
- (BOOL)isAuthorized;
- (BOOL)authorize;
- (void)storeAccessToken;
- (BOOL)restoreAccessToken;
- (void)deleteStoredAccessToken;
- (BOOL)authorize;
- (void)promptAuthorization;

- (NSString *) getClientip;

@property (nonatomic, strong) NSString *accessToken;
@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) NSTimeInterval expires_Time;
@property (nonatomic, strong) NSString *openid;
@property (nonatomic, strong) NSString *openkey;
@property (nonatomic,strong) NSString* clientip4QQ;
@end

@implementation QQWeiBoV2
@synthesize accessToken = _accessToken;
@synthesize name = _name;
@synthesize expires_Time=_expires_Time;
@synthesize openid = _openid;
@synthesize openkey = _openkey;
@synthesize clientip4QQ = clientip4QQ;

#pragma mark – init
+ (id) sharedInstance {
    static dispatch_once_t onceToken = 0;
    __strong static id _sharedObject = nil;
    dispatch_once(&onceToken, ^{
        _sharedObject = [[QQWeiBoV2 alloc]initWithHostName:@"open.t.qq.com/api" apiPath:nil customHeaderFields:nil];
    });
    return _sharedObject;
}

- (NSString *)sharerId
{
    return @"QQWeibBoV2";
}
- (NSString *)sharerName
{
    return @"腾讯微薄";
}

- (void) logout
{
   [NSHTTPCookieStorage deleteCookiesForURL:[NSURL URLWithString:authorizeURL]];
   return [self deleteStoredAccessToken];
}
- (BOOL)islogin
{
    return [self isAuthorized];
}
- (BOOL)autologin
{
    return [self authorize];
}

#pragma mark – OAuth 过程
- (NSString *) getClientip
{
    if ([clientip4QQ length]) {
        return clientip4QQ;
    }
#warning 通过公网服务获取当前设备公网地址，但该服务可能会失效 by kk，（最好由自己的服务器提供该服务）
    NSString* fakeip=[NSString stringWithFormat:@"%d.%d.%d.%d",
                      arc4random() % 250+1,
                      arc4random() % 250+1,
                      arc4random() % 250+1,
                      arc4random() % 250+1 ];
    
    MKNetworkOperation *op = [self operationWithURLString:@"http://automation.whatismyip.com/n09230945.asp" params:nil httpMethod:@"GET"];
    [op onCompletion:^(MKNetworkOperation *completedOperation)
     {
         DLog(@"Data from server %@", [completedOperation responseString]);
         NSString *ip = [completedOperation responseString];
         NSArray *array = [ip componentsSeparatedByString:@"."]; //从字符A中分隔成2个元素的数组
         if ([array count]==4 || [[array objectAtIndex:0]intValue]<=255 ||[[array objectAtIndex:1]intValue]<=255 ||[[array objectAtIndex:2]intValue]<=255 ||[[array objectAtIndex:3]intValue] <= 255 ) {
              self.clientip4QQ = ip;
         }else {
             self.clientip4QQ=fakeip;
         }
         
     }onError:^(MKNetworkOperation *completedOperation, NSError* error) {
         
         clientip4QQ = fakeip;
         DLog(@"Data from server %@", [completedOperation responseString]);
     }];
    
    [self enqueueOperation:op forceReload:YES];//强制请求
    
    return fakeip;
}

- (void)storeAccessToken
{	
     NSLog(@"%@,%@,%lf,%@",self.accessToken,self.name,self.expires_Time,self.sharerId);
	 NSString *sharerId = [self sharerId];
	[SHK setAuthValue:self.accessToken forKey:accessTokenKey forSharer:sharerId];
    [SHK setAuthValue:self.name forKey:usrname forSharer:sharerId];
    [SHK setAuthValue:[NSString stringWithFormat:@"%lf", self.expires_Time] forKey:expires_inKey forSharer:sharerId];
    [SHK setAuthValue:self.openid forKey:openid forSharer:sharerId];
    [SHK setAuthValue:self.openkey forKey:openkey forSharer:sharerId];
}

- (BOOL)restoreAccessToken
{
    if (self.expires_Time>0 && [[NSDate date] timeIntervalSince1970] > self.expires_Time){
        //时间过期，强制logout 
        [self deleteStoredAccessToken];
        return NO;
    }
    
	if ([self.accessToken length] && [self.name length] && [[NSDate date] timeIntervalSince1970] < self.expires_Time && 
        [self.openkey length] && [self.openid length])
		return YES;
    
    NSString *sharerId = [self sharerId];
	self.accessToken = [SHK getAuthValueForKey:accessTokenKey forSharer:sharerId];
    self.name = [SHK getAuthValueForKey:usrname forSharer:sharerId];
    self.expires_Time = [[SHK getAuthValueForKey:expires_inKey forSharer:sharerId]doubleValue];
    self.openid = [SHK getAuthValueForKey:openid forSharer:sharerId];
    self.openkey = [SHK getAuthValueForKey:openkey forSharer:sharerId];
	
    if ([[NSDate date] timeIntervalSince1970] > self.expires_Time){
        //时间过期，强制logout 
        [self deleteStoredAccessToken];
        return NO;
    }
    
    NSLog(@"%@,%@,%@,%@",self.accessToken,self.name,self.expires_Time,self.openid);
	return ([self.accessToken length] && [self.name length] && [[NSDate date] timeIntervalSince1970] < self.expires_Time && [self.openkey length] && [self.openid length]);
}

- (void)deleteStoredAccessToken
{
	NSString *sharerId = [self sharerId];
	
    [SHK removeAuthValueForKey:accessTokenKey forSharer:sharerId];
    [SHK removeAuthValueForKey:usrname forSharer:sharerId];
    [SHK removeAuthValueForKey:expires_inKey forSharer:sharerId];
    [SHK removeAuthValueForKey:openid forSharer:sharerId];
    [SHK removeAuthValueForKey:openkey forSharer:sharerId];
    
    self.accessToken =nil;
    self.name=nil;
    self.expires_Time=0;
    self.openid = nil;
    self.openkey = nil;
}

- (BOOL)isAuthorized
{		
	return [self restoreAccessToken];
}

- (void)promptAuthorization
{
    //https://open.t.qq.com/cgi-bin/oauth2/authorize?client_id=APP_KEY&response_type=code&redirect_uri=http://www.myurl.com/example
    NSURL* callbackURL=[NSURL URLWithString:qqWeiboV2RedirectURI];
	NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@?client_id=%@&response_type=code&redirect_uri=%@", authorizeURL, qqWeiboV2ClientId, [callbackURL.absoluteString URLEncodedString]]];
    
   // [[NSURLCache sharedURLCache] removeAllCachedResponses];
    
	SHKQQWeiBoV2OAuthView *auth = [[SHKQQWeiBoV2OAuthView alloc] initWithURL:url delegate:self];
	[[SHK currentHelper] showViewController:auth];	
	//[auth release];
}
- (void)tokenAuthorizeView:(SHKOAuthView *)authView didFinishWithSuccess:(BOOL)success queryParams:(NSMutableDictionary *)queryParams error:(NSError *)error
{
#warning 无网络状态下，授权页面会授权失败，此时，是否应该有所提示呢？
    if (!success && error) {
        NSLog(@"%@",[error localizedDescription]);
        [[SHK currentHelper] hideCurrentViewControllerAnimated:YES];
    }
    NSLog(@"tokenAuthorizeView");
}

- (NSURL *)authorizeCallbackURL
{
    NSLog(@"authorizeCallbackURL");
    return [NSURL URLWithString:qqWeiboV2RedirectURI];
}
- (BOOL)authorize
{
	if ([self isAuthorized])
		return YES;
	
	else 
		[self promptAuthorization];
	
	return NO;
}

- (void)tokenAuthorizeCancelledView:(SHKOAuthView *)authView
{
	[[SHK currentHelper] hideCurrentViewControllerAnimated:YES];	
    //[self authDidFinish:NO];
}

- (void)requestAccessTokenWithAuthorizeCode:(NSString *)code
{
    NSMutableDictionary *params = [NSMutableDictionary dictionaryWithObjectsAndKeys:qqWeiboV2ClientId, @"client_id",
                            qqWeiboV2SecretKey, @"client_secret",
                            @"authorization_code", @"grant_type",
                            qqWeiboV2RedirectURI, @"redirect_uri",
                            code, @"code", nil];
    
    //注意：获取token的apipath 与微薄功能调用api 路径不一致
    //https://open.t.qq.com/cgi-bin/oauth2/access_token?client_id=APP_KEY&client_secret=APP_SECRET&redirect_uri=http://www.myurl.com/example&grant_type=authorization_code&code=CODE
    MKNetworkOperation *op = [self operationWithURLString:@"https://open.t.qq.com/cgi-bin/oauth2/access_token"
                                              params:params
                                               httpMethod:@"GET"];//
    
    [op onCompletion:^(MKNetworkOperation *completedOperation)
     {
         
         //access_token=4d3edd8332622c5eb6da783c533f1baa&expires_in=604800&name=onlyyoujack
         [[SHK currentHelper] hideCurrentViewControllerAnimated:YES];

         NSString* accessString = [completedOperation responseString];
         NSRange rangeaccess_token = [accessString rangeOfString:@"access_token="];
         NSRange rangeexpires_in= [accessString rangeOfString:@"&expires_in="];
         NSRange rangename= [accessString rangeOfString:@"&name="];
         if (rangeaccess_token.location != NSNotFound && 
             rangeexpires_in.location != NSNotFound && 
             rangename.location != NSNotFound &&
             rangeexpires_in.location > rangeaccess_token.location &&
             rangename.location>rangeexpires_in.location){
             
             self.accessToken = [accessString substringWithRange:NSMakeRange(rangeaccess_token.location+rangeaccess_token.length,rangeexpires_in.location-rangeaccess_token.length-rangeaccess_token.location)];
             
             NSInteger seconds = [[accessString substringWithRange:NSMakeRange(rangeexpires_in.location+rangeexpires_in.length,rangename.location-rangeexpires_in.length-rangeexpires_in.location)]intValue];
             self.expires_Time = [[NSDate date] timeIntervalSince1970] + seconds;
             
             self.name = [accessString substringFromIndex:(rangename.location+rangename.length)];

            [self storeAccessToken];
                 
            // [self tryPendingAction];
            // [self tryToSend];
         }         
         
     }onError:^(MKNetworkOperation *completedOperation, NSError* error) {
         
         DLog(@"Data from server %@", [completedOperation responseString]);
     }];
    
    [self enqueueOperation:op forceReload:YES];//强制请求
    
}
- (void)authorizeWebView:(SHKQQWeiBoV2OAuthView *)webView didReceiveAuthorizeCode:(NSString *)code
{
    // 授权过程被 取消
    if (![code isEqualToString:@"21330"])//腾讯微薄，授权过程，页面取消，会返回登陆，而不是如新浪微薄授权一样，返回错误码
    {
        //注意查找数据的格式一定是：CODE&openid=OPENID&openkey=OPENKEY，否则查找错误
        //9e3de003990951cc56f6646b9626c2af&openid=B139AB11ADE25BA12569631675F79124&openkey=9C7050002B91A94C56A176B69FD48D93
        NSRange rangeopenid = [code rangeOfString:@"&openid="];
        NSRange rangeopenkey= [code rangeOfString:@"&openkey="];
        if (rangeopenid.location != NSNotFound && 
            rangeopenkey.location != NSNotFound && 
            rangeopenkey.location>rangeopenid.location) {
            
            NSString* token_code =  [code substringWithRange:NSMakeRange(0,rangeopenid.location)];
            NSString* token_openid= [code substringWithRange:NSMakeRange(rangeopenid.location + rangeopenid.length,rangeopenkey.location-rangeopenid.length-rangeopenid.location)];
            NSString* token_openkey=[code substringFromIndex:rangeopenkey.location+rangeopenkey.length];
            
            self.openid = token_openid;
            self.openkey = token_openkey;
            [self requestAccessTokenWithAuthorizeCode:token_code];
        }
        //todo:授权解析code错误的处理 by kk
        //add here
        [[SHK currentHelper] hideCurrentViewControllerAnimated:YES];
    }
    else 
    {
        [[SHK currentHelper] hideCurrentViewControllerAnimated:YES];
    }
}

#pragma mark – API接口
-(MKNetworkOperation*)  requestAPI:(NSString*)apiPath
                        httpMethod:(NSString *)httpMethod
                            params:(NSDictionary *)params
                      onCompletion:(QQWeiBoV2ResponseBlock) completionBlock
                           onError:(QQWeiBoV2ErrorBlock) errorBlock{
    
    
    if (![self authorize]) {
        return nil;
    }
    //=====================
    //https://open.t.qq.com/api/REQUEST_METHOD?oauth_consumer_key=APP_KEY&access_token=ACCESSTOKEN&openid=OPENID&clientip=CLIENTIP&oauth_version=2.a&scope=all
    //=====================
    NSMutableDictionary *mutableParams = [NSMutableDictionary dictionaryWithDictionary:params];
    [mutableParams setObject:qqWeiboV2ClientId forKey:@"oauth_consumer_key"];
    [mutableParams setObject:self.accessToken forKey:@"access_token"];
    [mutableParams setObject:self.openid forKey:@"openid"];
    
    [mutableParams setObject:[self getClientip] forKey:@"clientip"];
    [mutableParams setObject:@"2.a" forKey:@"oauth_version"];
    [mutableParams setObject:@"all" forKey:@"scope"];

    
    MKNetworkOperation *op = [self operationWithPath:apiPath
                                              params:mutableParams
                                          httpMethod:httpMethod
                                                 ssl:YES];//强制使用https
    
    [op onCompletion:^(MKNetworkOperation *completedOperation)
     {
         NSLog(@"%@",[completedOperation responseString]);
         completionBlock([[completedOperation responseString]objectFromJSONString]);
         
     }onError:^(MKNetworkOperation *completedOperation, NSError* error) {
         //============临时处理======
         NSMutableDictionary* dict = [[completedOperation responseString] objectFromJSONString];
         if ([dict isKindOfClass:[NSDictionary class]])
         {
             int error_code = [[dict objectForKey:@"error_code"] intValue] ;
             NSString* error= [dict objectForKey:@"error"];
             switch (error_code) {
                 case 21327:
                     NSLog(@"%@,%d",error,error_code);
                     
                     [self deleteStoredAccessToken];
                     break;
                     
                 default:
                     break;
             }
             
         }
         //========================
         errorBlock([[completedOperation responseString]objectFromJSONString], error);
     }];
    
    [self enqueueOperation:op forceReload:YES];//强制请求
    
    return op;
}

-(MKNetworkOperation*)  update:(NSString*)text
                         image:(UIImage *)image
                  onCompletion:(QQWeiBoV2ResponseBlock) completionBlock
                       onError:(QQWeiBoV2ErrorBlock) errorBlock{
    
    if (![self authorize]) {
        return nil;
    }
    //=====================
    //https://open.t.qq.com/api/REQUEST_METHOD?oauth_consumer_key=APP_KEY&access_token=ACCESSTOKEN&openid=OPENID&clientip=CLIENTIP&oauth_version=2.a&scope=all
    //=====================
    NSMutableDictionary *mutableParams = [NSMutableDictionary dictionaryWithDictionary:nil];
    [mutableParams setObject:qqWeiboV2ClientId forKey:@"oauth_consumer_key"];
    [mutableParams setObject:self.accessToken forKey:@"access_token"];
    [mutableParams setObject:self.openid forKey:@"openid"];
    
    
    [mutableParams setObject:[self getClientip] forKey:@"clientip"];
    [mutableParams setObject:@"2.a" forKey:@"oauth_version"];
    [mutableParams setObject:@"all" forKey:@"scope"];
    [mutableParams setObject:@"" forKey:@"jing"];
    [mutableParams setObject:@"" forKey:@"wei"];
    [mutableParams setObject:@"0" forKey:@"syncflag"];
    
    
    [mutableParams setObject:(text ? text : @"") forKey:@"content"];
    
    NSString* apiPath=@"";
    if (image) {
        apiPath=@"t/add_pic";
    }else{
        apiPath=@"t/add";
    }
    
    MKNetworkOperation *op = [self operationWithPath:apiPath
                                              params:mutableParams
                                          httpMethod:@"POST"
                                                 ssl:YES];//强制使用https
    
    if (image) {
        NSData* imageData = UIImagePNGRepresentation((UIImage *)image);
        [op addData:imageData forKey:@"pic" fileName:@"file.png" mimeType:@"image/png"];
        // setFreezable uploads your images after connection is restored!
        [op setFreezable:YES];
    }
    [op onCompletion:^(MKNetworkOperation *completedOperation)
     {
         completionBlock([[completedOperation responseString]objectFromJSONString]);
         
     }onError:^(MKNetworkOperation *completedOperation, NSError* error) {
         
         errorBlock([[completedOperation responseString]objectFromJSONString], error);
     }];
    
    [self enqueueOperation:op forceReload:YES];//强制请求
    
    return op;
}
//==================================
/*
-(void)getQQWeiboHomeTimeLine{
    
    if (![[QQWeiBoV2 sharedInstance] islogin]) {

    }
    //=========================================================================
    // http://wiki.open.t.qq.com/index.php/时间线/主页时间线
    //请求参数：oauth或openid&openkey标准参数，并带上以下参数
    //format 返回数据的格式（json或xml）
    //pageflag 分页标识（0：第一页，1：向下翻页，2：向上翻页）
    //pagetime 本页起始时间（第一页：填0，向上翻页：填上一次请求返回的第一条记录时间，向下翻页：填上一次请求返回的最后一条记录时间）
    //reqnum 每次请求记录的条数（1-70条）
    //type 拉取类型  0x1 原创发表 0x2 转载 0x8 回复 0x10 空回 0x20 提及 0x40 点评
    //如需拉取多个类型请使用|，如(0x1|0x2)得到3，此时type=3即可，填零表示拉取所有类型
    //contenttype 内容过滤。0-表示所有类型，1-带文本，2-带链接，4-带图片，8-带视频，0x10-带音频
    //http://open.t.qq.com/api/statuses/home_timeline?format=json&pageflag=0&reqnum=20&pagetime=0&type=0x1&contenttype=1
    //==========================================================================
    NSString* apiPath=@"statuses/home_timeline";
    NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:
                            @"json",@"format",//返回数据格式
                            @"0",@"pageflag",//分页标识
                            @"0",@"pagetime",//本页起始时间
                            @"2",@"reqnum",//请求条数
                            @"0",@"type",//类型，全部
                            @"0",@"contenttype",//内容分类
                            nil];
    
    MKNetworkOperation* op= [ [QQWeiBoV2 sharedInstance]  requestAPI:apiPath
                                                          httpMethod:@"GET"
                                                              params:params
                                                        onCompletion:^(NSDictionary* responseData){
                                                            //dosomething
                                                            NSLog(@"success");
                                                            
                                                        }onError:^(NSDictionary* responseData, NSError *error){
                                                            //dosomething
                                                            NSLog(@"error");
                                                        }];
    
}
*/
//===================================
@end
